package com.xmall.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xmall.bean.bo.GoodsBO;
import com.xmall.bean.bo.GoodsListBo;
import com.xmall.bean.table.*;
import com.xmall.bean.vo.*;
import com.xmall.bean.vo.goodsdetail.GoodsDetailCommentInfoVo;
import com.xmall.bean.vo.goodsdetail.GoodsDetailCommentVo;
import com.xmall.bean.vo.goodsdetail.GoodsDetailVo;
import com.xmall.bean.vo.goodsdetail.SpecificationInfoVo;
import com.xmall.mapper.*;

import org.apache.catalina.security.SecurityUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;

import com.xmall.service.GoodsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Connor
 * @ClassName: GoodsServiceImpl
 * @PackageName: com.xmall.service
 * @Description:
 * @date 2020/12/06
 * @Version 1.0
 */
@Service
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    GoodsMapper goodsMapper;

    @Autowired
    BrandMapper brandMapper;

    @Autowired
    CategoryMapper categoryMapper;

    @Autowired
    GoodsAttributeMapper goodsAttributeMapper;

    @Autowired
    GoodsProductMapper goodsProductMapper;

    @Autowired
    GoodsSpecificationMapper goodsSpecificationMapper;

    @Autowired
    GrouponRulesMapper grouponRulesMapper;

    @Autowired
    IssueMapper issueMapper;

    @Autowired
    CommentMapper commentMapper;

    @Autowired
    CartMapper cartMapper;

    @Autowired
    SearchHistoryMapper searchHistoryMapper;

    @Override
    public GoodsListVO<Goods> queryGoodsList(Integer page, Integer limit, Integer goodsSn, String name, String sort, String order) {
        PageHelper.startPage(page, limit);

        GoodsExample goodsExample = new GoodsExample();
        goodsExample.setOrderByClause(sort + " " + order);

        GoodsExample.Criteria criteria = goodsExample.createCriteria();
        if (goodsSn != null){
            criteria.andGoodsSnEqualTo(goodsSn);
        }
        if (name != null && name.length() != 0){
            criteria.andNameLike("%" + name + "%");
        }
        List<Goods> goodsList = goodsMapper.selectByExample(goodsExample);
        GoodsListVO<Goods> goodsGoodsListVO = new GoodsListVO<>();
        goodsGoodsListVO.setItems(goodsList);

        PageInfo<Goods> goodsPageInfo = new PageInfo<>(goodsList);
        goodsGoodsListVO.setTotal((int) goodsPageInfo.getTotal());
        return goodsGoodsListVO;
    }

    @Override
    public void createGoods(GoodsBO<GoodsSpecification, GoodsProduct, GoodsAttribute> goodsBO) {
        goodsMapper.insert(goodsBO.getGoods());
        Integer goodsId = goodsBO.getGoods().getId();
        for (GoodsAttribute attribute : goodsBO.getAttributes()) {
            attribute.setGoodsId(goodsId);
            goodsAttributeMapper.insert(attribute);
        }
        for (GoodsProduct product : goodsBO.getProducts()) {
            product.setGoodsId(goodsId);
            goodsProductMapper.insert(product);
        }
        for (GoodsSpecification specification : goodsBO.getSpecifications()) {
            specification.setGoodsId(goodsId);
            goodsSpecificationMapper.insert(specification);
        }
    }

    @Override
    public void updateGoods(GoodsBO<GoodsSpecification, GoodsProduct, GoodsAttribute> goodsBO) {
        goodsMapper.updateByPrimaryKeySelective(goodsBO.getGoods());
        for (GoodsAttribute attribute : goodsBO.getAttributes()) {
            goodsAttributeMapper.updateByPrimaryKeySelective(attribute);
        }
        for (GoodsProduct product : goodsBO.getProducts()) {
            goodsProductMapper.updateByPrimaryKeySelective(product);
        }
        for (GoodsSpecification specification : goodsBO.getSpecifications()) {
            goodsSpecificationMapper.updateByPrimaryKeySelective(specification);
        }
    }

    @Override
    public void deleteGoods(Goods goods) {
        GoodsExample goodsExample = new GoodsExample();
        GoodsExample.Criteria criteria = goodsExample.createCriteria();
        criteria.andIdEqualTo(goods.getId());
        Goods goods1 = new Goods();
        goods1.setDeleted(true);
        goodsMapper.updateByExampleSelective(goods1, goodsExample);
    }

    @Override
    public GoodsDetailVO<GoodsAttribute, GoodsSpecification, GoodsProduct> queryGoodsDetail(Integer id) {
        Goods goods = goodsMapper.selectByPrimaryKey(id);
        GoodsAttributeExample goodsAttributeExample = new GoodsAttributeExample();
        GoodsAttributeExample.Criteria goodsAttributeExampleCriteria = goodsAttributeExample.createCriteria();
        goodsAttributeExampleCriteria.andGoodsIdEqualTo(id);
        List<GoodsAttribute> goodsAttributes = goodsAttributeMapper.selectByExample(goodsAttributeExample);
        GoodsProductExample goodsProductExample = new GoodsProductExample();
        GoodsProductExample.Criteria goodsProductExampleCriteria = goodsProductExample.createCriteria();
        goodsProductExampleCriteria.andGoodsIdEqualTo(id);
        List<GoodsProduct> goodsProducts = goodsProductMapper.selectByExample(goodsProductExample);
        GoodsSpecificationExample goodsSpecificationExample = new GoodsSpecificationExample();
        GoodsSpecificationExample.Criteria goodsSpecificationExampleCriteria = goodsSpecificationExample.createCriteria();
        goodsSpecificationExampleCriteria.andGoodsIdEqualTo(id);
        List<GoodsSpecification> goodsSpecifications = goodsSpecificationMapper.selectByExample(goodsSpecificationExample);
        Category category = categoryMapper.selectByPrimaryKey(goods.getCategoryId());
        List<Integer> categoryIds = new ArrayList<>();
        categoryIds.add(category.getPid());
        categoryIds.add(goods.getCategoryId());

        return new GoodsDetailVO<>(goods, categoryIds, goodsAttributes, goodsSpecifications, goodsProducts);
    }

    @Override
    public GoodsCatAndBrandVO<GoodsCategoryVO, GoodsBrandVO> queryGoodsCatAndBrand() {
        BrandExample brandExample = new BrandExample();
        BrandExample.Criteria criteria1 = brandExample.createCriteria();
        criteria1.andDeletedEqualTo(false);
        List<Brand> brandList = brandMapper.selectByExample(brandExample);
        List<GoodsBrandVO> goodsBrandVOList = new ArrayList<>();
        for (Brand brand : brandList) {
            GoodsBrandVO goodsBrandVO = new GoodsBrandVO(brand.getId(), brand.getName());
            goodsBrandVOList.add(goodsBrandVO);
        }

        List<GoodsCategoryVO> categoryVOList = new ArrayList<>();
        CategoryExample categoryExample = new CategoryExample();
        CategoryExample.Criteria criteria = categoryExample.createCriteria();
        criteria.andPidEqualTo(0);
        List<Category> categoryList = categoryMapper.selectByExample(categoryExample);
        for (Category category : categoryList) {
            List<GoodsCategoryChildrenVO> goodsCategoryChildrenVOS = new ArrayList<>();
            CategoryExample example = new CategoryExample();
            CategoryExample.Criteria exampleCriteria = example.createCriteria();
            exampleCriteria.andPidEqualTo(category.getId());
            List<Category> categories = categoryMapper.selectByExample(example);
            for (Category category1 : categories) {
                goodsCategoryChildrenVOS.add(new GoodsCategoryChildrenVO(category1.getId(), category1.getName()));
            }
            categoryVOList.add(new GoodsCategoryVO(category.getId(), category.getName(), goodsCategoryChildrenVOS));
        }

        return new GoodsCatAndBrandVO<>(categoryVOList, goodsBrandVOList);
    }


    @Override
    public Integer countGoods() {
        return goodsMapper.countGoods();
    }

    @Override
    public WxGoodsCategoryVo queryCategory(Integer id) {
        Category currentCategory = categoryMapper.selectByPrimaryKey(id);
        CategoryExample categoryExample = new CategoryExample();
        CategoryExample.Criteria criteria = categoryExample.createCriteria();
        criteria.andPidEqualTo(currentCategory.getPid());
        List<Category> categorys = categoryMapper.selectByExample(categoryExample);
        Category parentCategory = categoryMapper.selectByPrimaryKey(currentCategory.getPid());
        return new WxGoodsCategoryVo(currentCategory, categorys, parentCategory);
    }

    //url为wx/goods/category
    @Override
    public WxGoodsCategoryVo WxGoodsCategory(String id) {
        WxGoodsCategoryVo wxGoodsCategoryVo = new WxGoodsCategoryVo();//等封装返回的对象

        CategoryExample categoryExample = new CategoryExample();
        CategoryExample.Criteria criteria = categoryExample.createCriteria();
        if(id != null && id != " "){
            criteria.andPidEqualTo(Integer.parseInt(id));
        }
        //1.请求参数id作为表category的pid查出List<Category> 并封装
        List<Category> categories = categoryMapper.selectByExample(categoryExample);
        wxGoodsCategoryVo.setBrotherCategory(categories);
        //2查出的List<Category>的首条数据 作为currentCategory 并封装
        Category category = categories.get(0);
        wxGoodsCategoryVo.setCurrentCategory(category);
        //3.请求参数id作为表categoty的id查出一条category作为parentCategory
        CategoryExample categoryExample1 = new CategoryExample();
        CategoryExample.Criteria criteria1 = categoryExample1.createCriteria();
        criteria1.andIdEqualTo(Integer.parseInt(id));
        List<Category> categories1 = categoryMapper.selectByExample(categoryExample1);
        Category category1 = categories1.get(0);
        wxGoodsCategoryVo.setParentCategory(category1);
        return wxGoodsCategoryVo;
    }

    @Override
    public GoodsDetailVo queryGoodsDetails(Integer id) {
        // 查询规格信息
        List<String> names = goodsSpecificationMapper.querySpecificationByGoodsId(id);
        ArrayList<SpecificationInfoVo> specificationList = new ArrayList<>();
        for (String name : names) {
            GoodsSpecificationExample goodsSpecificationExample = new GoodsSpecificationExample();
            GoodsSpecificationExample.Criteria criteria = goodsSpecificationExample.createCriteria();
            criteria.andSpecificationEqualTo(name).andDeletedEqualTo(false);
            List<GoodsSpecification> valueList = goodsSpecificationMapper.selectByExample(goodsSpecificationExample);
            specificationList.add(new SpecificationInfoVo(name, valueList));
        }
        // 查询团购信息
        GrouponRulesExample grouponRulesExample = new GrouponRulesExample();
        GrouponRulesExample.Criteria grouponRulesExampleCriteria = grouponRulesExample.createCriteria();
        grouponRulesExampleCriteria.andGoodsIdEqualTo(id);
        grouponRulesExampleCriteria.andDeletedEqualTo(false);
        List<GrouponRules> groupon = grouponRulesMapper.selectByExample(grouponRulesExample);
        // 查询问答信息
        // TODO: 可做优化，issue表添加category字段
        IssueExample issueExample = new IssueExample();
        List<Issue> issue = issueMapper.selectByExample(issueExample);
        // 查看商品是否被当前用户收藏
        Subject subject = SecurityUtils.getSubject();
        Integer userHasCollect = 0;
        User user = (User) subject.getPrincipal();
        if (user != null) {
            CartExample cartExample = new CartExample();
            CartExample.Criteria cartExampleCriteria = cartExample.createCriteria();
            cartExampleCriteria.andGoodsIdEqualTo(id).andUserIdEqualTo(user.getId());
            int count = (int) cartMapper.countByExample(cartExample);
            if (count > 0) userHasCollect = 1;
        }

        // 查看评论信息
        List<GoodsDetailCommentInfoVo> commentInfoVos = commentMapper.selectByGoodsId(id);
        //todo 已删除的评论不用显示出来
        GoodsDetailCommentVo comment = new GoodsDetailCommentVo(commentInfoVos, commentInfoVos.size());
        // 查看商品属性
        GoodsAttributeExample goodsAttributeExample = new GoodsAttributeExample();
        GoodsAttributeExample.Criteria goodsAttributeExampleCriteria = goodsAttributeExample.createCriteria();
        goodsAttributeExampleCriteria.andGoodsIdEqualTo(id).andDeletedEqualTo(false);
        List<GoodsAttribute> attribute = goodsAttributeMapper.selectByExample(goodsAttributeExample);
        //查看品牌商
        Brand brand = goodsMapper.queryBrandByGoodsId(id);
        // 查询商品product
        GoodsProductExample goodsProductExample = new GoodsProductExample();
        GoodsProductExample.Criteria goodsProductExampleCriteria = goodsProductExample.createCriteria();
        goodsProductExampleCriteria.andGoodsIdEqualTo(id).andDeletedEqualTo(false);
        List<GoodsProduct> productList = goodsProductMapper.selectByExample(goodsProductExample);
        // 查询商品详情
        Goods info = goodsMapper.selectByPrimaryKey(id);
        // 查看共享图片
        String shareImage = info.getShareUrl();

        return new GoodsDetailVo(specificationList, groupon, issue, userHasCollect, shareImage, comment, attribute, brand, productList, info);
    }

    @Override
    public GoodsRelatedVo queryRelatedGoods(Integer id) {
        Goods originalGoods = goodsMapper.selectByPrimaryKey(id);
        Integer categoryId = originalGoods.getCategoryId();
        GoodsExample goodsExample = new GoodsExample();
        GoodsExample.Criteria criteria = goodsExample.createCriteria();
        criteria.andCategoryIdEqualTo(categoryId).andDeletedEqualTo(false);
        List<Goods> goodsList = goodsMapper.selectByExample(goodsExample);
        ArrayList<GoodsRelatedInfoVo> goodsRelatedInfoVos = new ArrayList<>();
        for (Goods goods : goodsList) {
            goodsRelatedInfoVos.add(new GoodsRelatedInfoVo(goods.getId(), goods.getName(), goods.getBrief(), goods.getPicUrl(),
                    goods.getIsNew(), goods.getIsHot(), goods.getCounterPrice(), goods.getRetailPrice()));
        }
        return new GoodsRelatedVo(goodsRelatedInfoVos);

    }

    @Override
    public WxGoodsListVo queryGoodsListSelective(GoodsListBo goodsListBo) {
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        PageHelper.startPage(goodsListBo.getPage(), goodsListBo.getSize());
        GoodsExample goodsExample = new GoodsExample();
        if (goodsListBo.getSort() != null && goodsListBo.getOrder() != null) {
            goodsExample.setOrderByClause(goodsListBo.getSort() + " " + goodsListBo.getOrder());
        }
        GoodsExample.Criteria criteria = goodsExample.createCriteria();
        if (goodsListBo.getBrandId() != null) {
            criteria.andBrandIdEqualTo(goodsListBo.getBrandId());
        }
        if (goodsListBo.getCategoryId() != null && goodsListBo.getCategoryId() != 0) {
            criteria.andCategoryIdEqualTo(goodsListBo.getCategoryId());
        }
        //todo keyword模糊查询 用Name来对应
        SearchHistoryExample example = new SearchHistoryExample();
        SearchHistoryExample.Criteria exampleCriteria = example.createCriteria();
        if(goodsListBo.getKeyword() != null){
            criteria.andNameLike("%" + goodsListBo.getKeyword() + "%");
            exampleCriteria.andKeywordEqualTo(goodsListBo.getKeyword());
        }
        //todo  zp
        List<SearchHistory> searchHistories = searchHistoryMapper.selectByExample(example);
        if (searchHistories != null && searchHistories.size() == 0 && user != null) {
            searchHistoryMapper.insertSelective(new SearchHistory(null,
                    user.getId(),
                    goodsListBo.getKeyword(),
                    "wx",
                    new Date(),
                    new Date(),
                    false));
        }
        criteria.andDeletedEqualTo(false);
        List<Goods> goodsList = goodsMapper.selectByExample(goodsExample);
        ArrayList<WxGoodsListInfoVo> wxGoodsListInfoVos = new ArrayList<>();
        for (Goods goods : goodsList) {
            wxGoodsListInfoVos.add(new WxGoodsListInfoVo(goods.getId(), goods.getName(), goods.getBrief(), goods.getPicUrl(),
                    goods.getIsNew(), goods.getIsHot(), goods.getCounterPrice(), goods.getRetailPrice()));
        }
        CategoryExample categoryExample = new CategoryExample();
        CategoryExample.Criteria categoryExampleCriteria = categoryExample.createCriteria();
        categoryExampleCriteria.andLevelEqualTo("L2").andDeletedEqualTo(false);
        List<Category> categories = categoryMapper.selectByExample(categoryExample);
        return new WxGoodsListVo(wxGoodsListInfoVos, wxGoodsListInfoVos.size(), categories);
    }

}
